package com.smart.community.commons.test;

import com.smart.community.commons.service.BaseServiceCaller;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;

/**
 * 性能测试验证类
 * 
 * 验证Feign接口规范和下游服务调用规范的性能表现
 * 
 * @author Wu.Liang
 * @version 2.0.0
 * @since 2025-08-28
 */
@Slf4j
public class PerformanceValidation {
    
    /**
     * 验证性能表现
     */
    public static void validatePerformance() {
        log.info("开始验证性能表现...");
        
        // 验证BaseServiceCaller性能
        validateBaseServiceCallerPerformance();
        
        // 验证并发性能
        validateConcurrencyPerformance();
        
        // 验证内存使用性能
        validateMemoryPerformance();
        
        log.info("性能验证完成！");
    }
    
    /**
     * 验证BaseServiceCaller性能
     */
    private static void validateBaseServiceCallerPerformance() {
        log.info("验证BaseServiceCaller性能...");
        
        TestPerformanceServiceCaller serviceCaller = new TestPerformanceServiceCaller();
        
        // 测试单次调用性能
        validateSingleCallPerformance(serviceCaller);
        
        // 测试批量调用性能
        validateBatchCallPerformance(serviceCaller);
        
        // 测试异常处理性能
        validateExceptionHandlingPerformance(serviceCaller);
        
        log.info("✅ BaseServiceCaller性能验证通过");
    }
    
    /**
     * 验证单次调用性能
     */
    private static void validateSingleCallPerformance(TestPerformanceServiceCaller serviceCaller) {
        log.info("验证单次调用性能...");
        
        int iterations = 10000;
        long startTime = System.currentTimeMillis();
        
        for (int i = 0; i < iterations; i++) {
            serviceCaller.testNormalCall();
        }
        
        long endTime = System.currentTimeMillis();
        long duration = endTime - startTime;
        double avgTime = (double) duration / iterations;
        
        log.info("单次调用性能测试结果:");
        log.info("  总调用次数: {}", iterations);
        log.info("  总耗时: {}ms", duration);
        log.info("  平均耗时: {:.4f}ms", avgTime);
        log.info("  每秒调用次数: {:.2f}", (double) iterations / duration * 1000);
        
        // 性能基准：平均每次调用不超过1ms
        if (avgTime < 1.0) {
            log.info("✅ 单次调用性能验证通过");
        } else {
            log.warn("⚠️ 单次调用性能略低于预期，平均耗时: {:.4f}ms", avgTime);
        }
    }
    
    /**
     * 验证批量调用性能
     */
    private static void validateBatchCallPerformance(TestPerformanceServiceCaller serviceCaller) {
        log.info("验证批量调用性能...");
        
        int batchSize = 1000;
        int iterations = 100;
        long startTime = System.currentTimeMillis();
        
        for (int i = 0; i < iterations; i++) {
            List<String> items = generateTestItems(batchSize);
            serviceCaller.testBatchCall(items);
        }
        
        long endTime = System.currentTimeMillis();
        long duration = endTime - startTime;
        long totalItems = (long) batchSize * iterations;
        double avgTime = (double) duration / totalItems;
        
        log.info("批量调用性能测试结果:");
        log.info("  批次大小: {}", batchSize);
        log.info("  批次数: {}", iterations);
        log.info("  总项目数: {}", totalItems);
        log.info("  总耗时: {}ms", duration);
        log.info("  平均每项耗时: {:.4f}ms", avgTime);
        log.info("  每秒处理项目数: {:.2f}", (double) totalItems / duration * 1000);
        
        // 性能基准：平均每项处理不超过0.1ms
        if (avgTime < 0.1) {
            log.info("✅ 批量调用性能验证通过");
        } else {
            log.warn("⚠️ 批量调用性能略低于预期，平均每项耗时: {:.4f}ms", avgTime);
        }
    }
    
    /**
     * 验证异常处理性能
     */
    private static void validateExceptionHandlingPerformance(TestPerformanceServiceCaller serviceCaller) {
        log.info("验证异常处理性能...");
        
        int iterations = 10000;
        long startTime = System.currentTimeMillis();
        
        for (int i = 0; i < iterations; i++) {
            serviceCaller.testExceptionCall();
        }
        
        long endTime = System.currentTimeMillis();
        long duration = endTime - startTime;
        double avgTime = (double) duration / iterations;
        
        log.info("异常处理性能测试结果:");
        log.info("  总调用次数: {}", iterations);
        log.info("  总耗时: {}ms", duration);
        log.info("  平均耗时: {:.4f}ms", avgTime);
        log.info("  每秒调用次数: {:.2f}", (double) iterations / duration * 1000);
        
        // 性能基准：异常处理平均每次调用不超过2ms
        if (avgTime < 2.0) {
            log.info("✅ 异常处理性能验证通过");
        } else {
            log.warn("⚠️ 异常处理性能略低于预期，平均耗时: {:.4f}ms", avgTime);
        }
    }
    
    /**
     * 验证并发性能
     */
    private static void validateConcurrencyPerformance() {
        log.info("验证并发性能...");
        
        int threadCount = 10;
        int callsPerThread = 1000;
        ExecutorService executor = Executors.newFixedThreadPool(threadCount);
        
        long startTime = System.currentTimeMillis();
        
        List<CompletableFuture<Void>> futures = new ArrayList<>();
        
        for (int i = 0; i < threadCount; i++) {
            final int threadId = i;
            CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                TestPerformanceServiceCaller serviceCaller = new TestPerformanceServiceCaller();
                for (int j = 0; j < callsPerThread; j++) {
                    serviceCaller.testNormalCall();
                }
                log.debug("线程{}完成{}次调用", threadId, callsPerThread);
            }, executor);
            
            futures.add(future);
        }
        
        // 等待所有线程完成
        CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
        
        long endTime = System.currentTimeMillis();
        long duration = endTime - startTime;
        long totalCalls = (long) threadCount * callsPerThread;
        double avgTime = (double) duration / totalCalls;
        
        log.info("并发性能测试结果:");
        log.info("  线程数: {}", threadCount);
        log.info("  每线程调用数: {}", callsPerThread);
        log.info("  总调用次数: {}", totalCalls);
        log.info("  总耗时: {}ms", duration);
        log.info("  平均耗时: {:.4f}ms", avgTime);
        log.info("  每秒调用次数: {:.2f}", (double) totalCalls / duration * 1000);
        
        // 性能基准：并发环境下平均每次调用不超过1.5ms
        if (avgTime < 1.5) {
            log.info("✅ 并发性能验证通过");
        } else {
            log.warn("⚠️ 并发性能略低于预期，平均耗时: {:.4f}ms", avgTime);
        }
        
        executor.shutdown();
        try {
            if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
                executor.shutdownNow();
            }
        } catch (InterruptedException e) {
            executor.shutdownNow();
            Thread.currentThread().interrupt();
        }
    }
    
    /**
     * 验证内存使用性能
     */
    private static void validateMemoryPerformance() {
        log.info("验证内存使用性能...");
        
        // 记录初始内存使用
        Runtime runtime = Runtime.getRuntime();
        long initialMemory = runtime.totalMemory() - runtime.freeMemory();
        
        // 执行大量调用
        TestPerformanceServiceCaller serviceCaller = new TestPerformanceServiceCaller();
        int iterations = 100000;
        
        for (int i = 0; i < iterations; i++) {
            serviceCaller.testNormalCall();
            serviceCaller.testExceptionCall();
            
            // 每10000次调用检查一次内存
            if (i % 10000 == 0) {
                System.gc(); // 建议垃圾回收
            }
        }
        
        // 记录最终内存使用
        long finalMemory = runtime.totalMemory() - runtime.freeMemory();
        long memoryIncrease = finalMemory - initialMemory;
        
        log.info("内存使用性能测试结果:");
        log.info("  初始内存使用: {}MB", initialMemory / 1024 / 1024);
        log.info("  最终内存使用: {}MB", finalMemory / 1024 / 1024);
        log.info("  内存增长: {}MB", memoryIncrease / 1024 / 1024);
        log.info("  平均每次调用内存增长: {:.6f}KB", (double) memoryIncrease / iterations / 1024);
        
        // 性能基准：内存增长不超过100MB
        if (memoryIncrease < 100 * 1024 * 1024) {
            log.info("✅ 内存使用性能验证通过");
        } else {
            log.warn("⚠️ 内存使用性能略低于预期，内存增长: {}MB", memoryIncrease / 1024 / 1024);
        }
    }
    
    /**
     * 生成测试数据
     */
    private static List<String> generateTestItems(int count) {
        List<String> items = new ArrayList<>();
        for (int i = 0; i < count; i++) {
            items.add("item_" + i);
        }
        return items;
    }
    
    /**
     * 测试性能服务调用器
     */
    private static class TestPerformanceServiceCaller extends BaseServiceCaller {
        
        public String testNormalCall() {
            return safeCall("测试服务", "normalCall", () -> "success", "default");
        }
        
        public String testExceptionCall() {
            return safeCall("测试服务", "exceptionCall", () -> {
                throw new RuntimeException("测试异常");
            }, "default");
        }
        
        public List<String> testBatchCall(List<String> items) {
            Function<String, String> processor = item -> "processed_" + item;
            return safeBatchCall("测试服务", "batchCall", items, processor);
        }
    }
}
